﻿using System;
using System.Data;
using DTO.Clases;
using Npgsql;

namespace DataAccessLayer.Clases
{
    /// <summary>
    /// Representa una clase para la tranzacion a base de datos de Facturas de Proveedor.
    /// </summary>
    public class DaoFacturaProveedor
    {
        #region Tranzación a base de datos

        /// <summary>
        /// Proporciona acceso a la conexion a base de datos PostgreSQL.
        /// </summary>
        private Conexion miConexion;

        /// <summary>
        /// Representa un comando de ejecucion de sentencias SQL a PostgreSQL.
        /// </summary>
        private NpgsqlCommand miComando;

        /// <summary>
        /// Representa un adaptador de comandos SQL a PostgreSQL.
        /// </summary>
        private NpgsqlDataAdapter miAdapter;

        #endregion

        #region Funciones

        /// <summary>
        /// Representa la funcion recuperar_consecutivo.
        /// </summary>
        private const string ObtenerConsecutivo = "recuperar_consecutivo";

        /// <summary>
        /// Representa la funcion actualizar_consecutivo.
        /// </summary>
        private const string ActualizarConsecutivo = "actualizar_consecutivo";

        /// <summary>
        /// Representa la funcion insertar_factura_proveedor.
        /// </summary>
        private const string sqlInsertar = "insertar_factura_proveedor";

        /// <summary>
        /// Representa la función editar_factura_proveedor.
        /// </summary>
        private const string sqlEditar = "editar_factura_proveedor";

        /// <summary>
        /// Representa la función consulta_factura_proveedor.
        /// </summary>
        private const string sqlConsultaFactura = "consulta_factura_proveedor";

        /// <summary>
        /// Representa la función consulta_factura_proveedor_codigo.
        /// </summary>
        private const string sqlConsultaFacturaNumero = "consulta_factura_proveedor_codigo";

        /// <summary>
        /// Representa la funcion: count_consulta_factura_proveedor_codigo.
        /// </summary>
        private const string sqlCountFacturaNumero = "count_consulta_factura_proveedor_codigo";

        /// <summary>
        /// Representa la función consulta_factura_proveedor_fecha.
        /// </summary>
        private const string sqlConsultaFacturaFecha = "consulta_factura_proveedor_fecha";

        /// <summary>
        /// Representa la funcion count_consulta_factura_proveedor_fecha.
        /// </summary>
        private const string sqlCountFacturaFecha = "count_consulta_factura_proveedor_fecha";

        /// <summary>
        /// Representa la funcion consulta_factura_proveedor_periodo.
        /// </summary>
        private const string sqlConsultaFacturaPeriodo = "consulta_factura_proveedor_periodo";//

        /// <summary>
        /// Representa la funcion count_consulta_factura_proveedor_periodo.
        /// </summary>
        private const string sqlCountFacturaPeriodo = "count_consulta_factura_proveedor_periodo";

        /// <summary>
        /// Representa la función consulta_producto_factura_proveedor.
        /// </summary>
        private const string sqlConsultaProductoFactura = "consulta_producto_factura_proveedor";

        /// <summary>
        /// Representa la función consulta_factura_proveedor_codigo_activa.
        /// </summary>
        private const string sqlConsultaFacturaNumeroActiva = "consulta_factura_proveedor_codigo_activa";

        /// <summary>
        /// Representa la función count_consulta_factura_proveedor_codigo_activa.
        /// </summary>
        private const string sqlCountFacturaNumeroActiva = "count_consulta_factura_proveedor_codigo_activa";

        /// <summary>
        /// Representa la función consulta_factura_proveedor_fecha_activa.
        /// </summary>
        private const string sqlConsultaFacturaFechaActiva = "consulta_factura_proveedor_fecha_activa";

        /// <summary>
        /// Representa la función count_consulta_factura_proveedor_fecha_activa.
        /// </summary>
        private const string sqlCountFacturaFechaActiva = "count_consulta_factura_proveedor_fecha_activa";

        /// <summary>
        /// Representa la función consulta_factura_proveedor_periodo_activa.
        /// </summary>
        private const string sqlConsultaFacturaPeriodoActiva = "consulta_factura_proveedor_periodo_activa";

        /// <summary>
        /// Representa la función count_consulta_factura_proveedor_periodo_activa.
        /// </summary>
        private const string sqlCountFacturaPeriodoActiva = "count_consulta_factura_proveedor_periodo_activa";

        #endregion

        #region Mensajes

        /// <summary>
        /// Representa el texto: Ocurrio un error al actualizar el Lote.
        /// </summary>
        private const string EActualizaConsecutivo = "Ocurrio un error al actualizar el Lote.\n";

        /// <summary>
        /// Representa el texto: Ocurrio un error al obtener el númeor de Lote.
        /// </summary>
        private const string EObtenerConsecutivo = "Ocurrio un error al obtener el númeor de Lote.\n";

        /// <summary>
        /// Representa el texto: Ocurrion un error al ingresar la Facutar del Proveedor..
        /// </summary>
        private const string EIngresarFactura = "Ocurrio un error al ingresar la Facutar del Proveedor.\n";

        /// <summary>
        /// Representa el texto: Ocurrio un error al consultar la Factura del Proveedor.
        /// </summary>
        private const string EConsultaFacturaProveedor = "Ocurrio un error al consultar la Factura del Proveedor.\n";

        /// <summary>
        /// Representa el mensaje: Ocurrio un error al cargar el conteo total de registros.
        /// </summary>
        private const string ECountRows = "Ocurrio un error al cargar el conteo total de registros.\n";

        /// <summary>
        /// Ocurrio un error al cargar los Productos de la Factura.
        /// </summary>
        private const string EConsultaProductoFactura = "Ocurrio un error al cargar los Productos de la Factura.\n";

        /// <summary>
        /// Represent el texto: Ocurrio un error al editar los datos de la Factura de Proveedor.
        /// </summary>
        private const string EEditarFactura = "Ocurrio un error al editar los datos de la Factura de Proveedor.\n";

        #endregion

        /// <summary>
        /// Inicializa una nueva instancia de la clase DaoFacturaProveedor.
        /// </summary>
        public DaoFacturaProveedor()
        {
            this.miConexion = new Conexion();
        }

        /// <summary>
        /// Obtiene el consecutivo del número del Lote.
        /// </summary>
        /// <returns></returns>
        public string ObtenerNumeroLote()
        {
            try
            {
                CargarComando(ObtenerConsecutivo);
                miComando.Parameters.AddWithValue("cocepto", "Lote");
                miConexion.MiConexion.Open();
                var numeroLote = Convert.ToString(miComando.ExecuteScalar());
                miConexion.MiConexion.Close();
                miComando.Dispose();
                return numeroLote;
            }
            catch (Exception ex)
            {
                throw new Exception(EObtenerConsecutivo + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Actualiza el registro consecutivo del lote.
        /// </summary>
        /// <param name="lote">Número de lote a actualizar.</param>
        public void ActualizarLote(int lote)
        {
            var numero = lote + 1;
            try
            {
                CargarComando(ActualizarConsecutivo);
                miComando.Parameters.AddWithValue("concepto", "Lote");
                miComando.Parameters.AddWithValue("numero", numero.ToString());
                miConexion.MiConexion.Open();
                miComando.ExecuteNonQuery();
                miConexion.MiConexion.Close();
                miComando.Dispose();
            }
            catch (Exception ex)
            {
                throw new Exception(EActualizaConsecutivo + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Ingresa toda la información necesaria del registro de Factura de Proveedor.
        /// </summary>
        /// <param name="miFactura">Factura a ingresar.</param>
        public int IngresarFactura(FacturaProveedor miFactura)
        {
            var miDaoFacturaProducto = new DaoProductoFacturaProveedor();
            var miDaoProveedor = new DaoProveedor();
            var miDaoInventario = new DaoInventario();
            var miDaoLote = new DaoLote();
            try
            {
                CargarComando(sqlInsertar);
                miComando.Parameters.AddWithValue("proveedor", miFactura.Proveedor.CodigoInternoProveedor);
                miComando.Parameters.AddWithValue("pago", miFactura.EstadoFactura.Id);
                miComando.Parameters.AddWithValue("caja", miFactura.Caja.Id);
                miComando.Parameters.AddWithValue("usuario", miFactura.Usuario.Id);
                miComando.Parameters.AddWithValue("numero", miFactura.Numero);
                miComando.Parameters.AddWithValue("limite", miFactura.FechaLimite);
                miComando.Parameters.AddWithValue("fecha", miFactura.FechaIngreso);
                miComando.Parameters.AddWithValue("estado", miFactura.Estado);
                miComando.Parameters.AddWithValue("descuento", miFactura.Descuento);
                miConexion.MiConexion.Open();
                var id = Convert.ToInt32(miComando.ExecuteScalar());
                miConexion.MiConexion.Close();
                miComando.Dispose();
                foreach (var productos in miFactura.Productos)
                {
                    productos.IdFactura = id;
                    productos.Lote.Id = miDaoLote.IngresarLote(productos.Lote);
                    miDaoFacturaProducto.IngresarProductoFacturaProveedor(productos);
                    miDaoProveedor.IngresarProductoDeProveedor
                        (miFactura.Proveedor.CodigoInternoProveedor, productos.Producto.CodigoInternoProducto);
                    miDaoInventario.ActualizarInventario(productos.Inventario, false);
                }
                return id;
            }
            catch (Exception ex)
            {
                throw new Exception(EIngresarFactura + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Obtiene los registros de la consulta de una Factura de Proveedor.
        /// </summary>
        /// <param name="id">Número de identificación unico de la Factura.</param>
        /// <returns></returns>
        public FacturaProveedor ConsultaFacturaProveedor(int id)
        {
            var factura = new FacturaProveedor();
            try
            {
                CargarComando(sqlConsultaFactura);
                miComando.Parameters.AddWithValue("id", id);
                miConexion.MiConexion.Open();
                NpgsqlDataReader miReader = miComando.ExecuteReader();
                while (miReader.Read())
                {
                    factura.Id = miReader.GetInt32(0);
                    factura.Proveedor.CodigoInternoProveedor = miReader.GetInt32(1);
                    factura.EstadoFactura.Id = miReader.GetInt32(2);
                    factura.Caja.Id = miReader.GetInt32(3);
                    factura.Usuario.Id = miReader.GetInt32(4);
                    factura.Numero = miReader.GetString(5);
                    factura.FechaLimite = miReader.GetDateTime(6);
                    factura.FechaIngreso = miReader.GetDateTime(7);
                    factura.Estado = miReader.GetBoolean(8);
                    factura.Descuento = miReader.GetDouble(9);
                }
                miConexion.MiConexion.Close();
                miComando.Dispose();
                return factura;
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaFacturaProveedor + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Obtiene los registros de la consulta de una Factura de Proveedor.
        /// </summary>
        /// <param name="numero">Número de la Factura a consultar.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <returns></returns>
        public DataTable ConsultaFacturaProveedor(string numero, bool activa)
        {
            var tabla = new DataTable();
            try
            {
                if (!activa)
                {
                    CargarAdapter(sqlConsultaFacturaNumeroActiva);
                }
                else
                {
                    CargarAdapter(sqlConsultaFacturaNumero);
                }
                miAdapter.SelectCommand.Parameters.AddWithValue("numero", numero);
                miAdapter.Fill(tabla);
                return tabla;
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaFacturaProveedor + ex.Message);
            }
        }

        /// <summary>
        /// Obtiene los registros de la consulta de una Factura de Proveedor.
        /// </summary>
        /// <param name="codigo">Codigo del Proveedor a consultar.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <param name="registroBase">Registro base para la consulta.</param>
        /// <param name="registroMax">Número de registros a recuperar.</param>
        /// <returns></returns>
        public DataTable ConsultaFacturaProveedor(int codigo, bool activa, int registroBase, int registroMax)
        {
            var dataSet = new DataSet();
            try
            {
                if (!activa)
                {
                    CargarAdapter(sqlConsultaFacturaNumeroActiva);
                }
                else
                {
                    CargarAdapter(sqlConsultaFacturaNumero);
                }
                miAdapter.SelectCommand.Parameters.AddWithValue("codigo", codigo);
                miAdapter.Fill(dataSet, registroBase, registroMax, "factura");
                return dataSet.Tables[0];
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaFacturaProveedor + ex.Message);
            }
        }

        /// <summary>
        /// Obtiene el total de registros de una consulta de Factura de Proveedor.
        /// </summary>
        /// <param name="codigo">Codigo del Proveedor a consultar.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <returns></returns>
        public long GetRowsConsultaFacturaProveedor(int codigo, bool activa)
        {
            try
            {
                if (!activa)
                {
                    CargarComando(sqlCountFacturaNumeroActiva);
                }
                else
                {
                    CargarComando(sqlCountFacturaNumero);
                }
                miComando.Parameters.AddWithValue("codigo", codigo);
                miConexion.MiConexion.Open();
                var rows = Convert.ToInt64(miComando.ExecuteScalar());
                miConexion.MiConexion.Close();
                miComando.Dispose();
                return rows;
            }
            catch (Exception ex)
            {
                throw new Exception(ECountRows + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Obtiene los registros de la consulta de una Factura de Proveedor.
        /// </summary>
        /// <param name="fecha">Fecha con la cual se compara la fecha con la que ingreso la Factura.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <param name="registroBase">Registro base para la consulta.</param>
        /// <param name="registroMax">Número de registros a recuperar.</param>
        /// <returns></returns>
        public DataTable ConsultaFacturaProveedor
            (DateTime fecha, bool activa, int registroBase, int registroMax)
        {
            var dataSet = new DataSet();
            try
            {
                if (!activa)
                {
                    CargarAdapter(sqlConsultaFacturaFechaActiva);
                }
                else
                {
                    CargarAdapter(sqlConsultaFacturaFecha);
                }
                miAdapter.SelectCommand.Parameters.AddWithValue("fecha", fecha);
                miAdapter.Fill(dataSet, registroBase, registroMax, "factura");
                return dataSet.Tables[0];
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaFacturaProveedor + ex.Message);
            }
        }

        /// <summary>
        /// Obtiene el total de registros de una consulta de Factura de Proveedor.
        /// </summary>
        /// <param name="fecha">Fecha con la cual se compara la fecha con la que ingreso la Factura.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <returns></returns>
        public long GetRowsConsultaFacturaProveedor(DateTime fecha, bool activa)
        {
            try
            {
                if (!activa)
                {
                    CargarComando(sqlCountFacturaFechaActiva);
                }
                else
                {
                    CargarComando(sqlCountFacturaFecha);
                }
                miComando.Parameters.AddWithValue("fecha", fecha);
                miConexion.MiConexion.Open();
                var rows = Convert.ToInt64(miComando.ExecuteScalar());
                miConexion.MiConexion.Close();
                miComando.Dispose();
                return rows;
            }
            catch (Exception ex)
            {
                throw new Exception(ECountRows + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Obtiene los registros de la consulta de una Factura de Proveedor.
        /// </summary>
        /// <param name="codigo">Codigo del Proveedor a consultar.</param>
        /// <param name="fecha">Fecha con la cual se compara la fecha con la que ingreso la Factura.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <returns></returns>
        public DataTable ConsultaFacturaProveedor(int codigo, DateTime fecha, bool activa)
        {
            var tabla = new DataTable();
            try
            {
                if (!activa)
                {
                    CargarAdapter(sqlConsultaFacturaFechaActiva);
                }
                else
                {
                    CargarAdapter(sqlConsultaFacturaFecha);
                }
                miAdapter.SelectCommand.Parameters.AddWithValue("codigo", codigo);
                miAdapter.SelectCommand.Parameters.AddWithValue("fecha", fecha);
                miAdapter.Fill(tabla);
                return tabla;
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaFacturaProveedor + ex.Message);
            }
        }

        /// <summary>
        /// Obtiene los registros de la consulta de una Factura de Proveedor.
        /// </summary>
        /// <param name="fecha1">Primer fecha que proporciona el periodo.</param>
        /// <param name="fecha2">Segunda fecha que proporciona el periodo.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <param name="registroBase">Registro base para la consulta.</param>
        /// <param name="registroMax">Número de registros a recuperar.</param>
        /// <returns></returns>
        public DataTable ConsultaFacturaProveedor
            (DateTime fecha1, DateTime fecha2, bool activa, int registroBase, int registroMax)
        {
            var dataSet = new DataSet();
            try
            {
                if (!activa)
                {
                    CargarAdapter(sqlConsultaFacturaPeriodoActiva);
                }
                else
                {
                    CargarAdapter(sqlConsultaFacturaPeriodo);
                }
                miAdapter.SelectCommand.Parameters.AddWithValue("fecha1", fecha1);
                miAdapter.SelectCommand.Parameters.AddWithValue("fecha2", fecha2);
                miAdapter.Fill(dataSet, registroBase, registroMax, "factura");
                return dataSet.Tables[0];
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaFacturaProveedor + ex.Message);
            }
        }

        /// <summary>
        /// Obtiene el total de registros de una consulta de Factura de Proveedor.
        /// </summary>
        /// <param name="fecha1">Primer fecha que proporciona el periodo.</param>
        /// <param name="fecha2">Segunda fecha que proporciona el periodo.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <returns></returns>
        public long GetRowsConsultaFacturaProveedor(DateTime fecha1, DateTime fecha2, bool activa)
        {
            try
            {
                if (!activa)
                {
                    CargarComando(sqlCountFacturaPeriodoActiva);
                }
                else
                {
                    CargarComando(sqlCountFacturaPeriodo);
                }
                miComando.Parameters.AddWithValue("fecha1", fecha1);
                miComando.Parameters.AddWithValue("fecha2", fecha2);
                miConexion.MiConexion.Open();
                var rows = Convert.ToInt64(miComando.ExecuteScalar());
                miConexion.MiConexion.Close();
                miComando.Dispose();
                return rows;
            }
            catch (Exception ex)
            {
                throw new Exception(ECountRows + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Obtiene los registros de la consulta de una Factura de Proveedor.
        /// </summary>
        /// <param name="codigo">Codigo del Proveedor a consultar.</param>
        /// <param name="fecha1">Primer fecha que proporciona el periodo.</param>
        /// <param name="fecha2">Segunda fecha que proporciona el periodo.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <param name="registroBase">Registro base para la consulta.</param>
        /// <param name="registroMax">Número de registros a recuperar.</param>
        /// <returns></returns>
        public DataTable ConsultaFacturaProveedor
            (int codigo, DateTime fecha1, DateTime fecha2, bool activa, int registroBase, int registroMax)
        {
            var dataSet = new DataSet();
            try
            {
                if (!activa)
                {
                    CargarAdapter(sqlConsultaFacturaPeriodoActiva);
                }
                else
                {
                    CargarAdapter(sqlConsultaFacturaPeriodo);
                }
                miAdapter.SelectCommand.Parameters.AddWithValue("codigo", codigo);
                miAdapter.SelectCommand.Parameters.AddWithValue("fecha1", fecha1);
                miAdapter.SelectCommand.Parameters.AddWithValue("fecha2", fecha2);
                miAdapter.Fill(dataSet, registroBase, registroMax, "factura");
                return dataSet.Tables[0];
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaFacturaProveedor + ex.Message);
            }
        }

        /// <summary>
        /// Obtiene el total de registros de una consulta de Factura de Proveedor.
        /// </summary>
        /// <param name="codigo">Codigo del Proveedor a consultar.</param>
        /// <param name="fecha1">Primer fecha que proporciona el periodo.</param>
        /// <param name="fecha2">Segunda fecha que proporciona el periodo.</param>
        /// <param name="activa">Indica si solo se recupera registros activos.</param>
        /// <returns></returns>
        public long GetRowsConsultaFacturaProveedor
            (int codigo, DateTime fecha1, DateTime fecha2, bool activa)
        {
            try
            {
                if (!activa)
                {
                    CargarComando(sqlCountFacturaPeriodoActiva);
                }
                else
                {
                    CargarComando(sqlCountFacturaPeriodo);
                }
                miComando.Parameters.AddWithValue("codigo", codigo);
                miComando.Parameters.AddWithValue("fecha1", fecha1);
                miComando.Parameters.AddWithValue("fecha2", fecha2);
                miConexion.MiConexion.Open();
                var rows = Convert.ToInt64(miComando.ExecuteScalar());
                miConexion.MiConexion.Close();
                miComando.Dispose();
                return rows;
            }
            catch (Exception ex)
            {
                throw new Exception(ECountRows + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Obtiene los registros de los producto relacionado a una Factura de Proveedor.
        /// </summary>
        /// <param name="id">Id de la Factura consultada.</param>
        /// <returns></returns>
        public DataTable ConsultaProductoFacturaProveedor(int id)//Toca pasalo...
        {
            var tabla = new DataTable();
            try
            {
                CargarAdapter(sqlConsultaProductoFactura);
                miAdapter.SelectCommand.Parameters.AddWithValue("id", id);
                miAdapter.Fill(tabla);
                return tabla;
            }
            catch (Exception ex)
            {
                throw new Exception(EConsultaProductoFactura + ex.Message);
            }
        }

        /// <summary>
        /// Edita los datos de un registro de FacturaProveedor en base de datos.
        /// </summary>
        /// <param name="factura">Registro de FacturaProveedor a editar.</param>
        public void EditarFacturaProveedor(FacturaProveedor factura)
        {
            var miDaoProveedor = new DaoProveedor();
            var miDaoProducto = new DaoProducto();
            var miDaoFacturaProducto = new DaoProductoFacturaProveedor();
            var miDaoInventario = new DaoInventario();
            try
            {
                var tempFactura = ConsultaFacturaProveedor(factura.Id);
                var proveedorActual = miDaoProveedor.ConsultarPrveedorBasico
                    (tempFactura.Proveedor.CodigoInternoProveedor);
                var proveedorNew = miDaoProveedor.ConsultarPrveedorBasico
                    (factura.Proveedor.CodigoInternoProveedor);
                var productos = ConsultaProductoFacturaProveedor(factura.Id);
                if (factura.Proveedor.CodigoInternoProveedor != tempFactura.Proveedor.CodigoInternoProveedor)
                {
                    if (proveedorActual.IdRegimen != proveedorNew.IdRegimen)
                    {

                        ProductoFacturaProveedor miProducto;
                        if (proveedorNew.IdRegimen == 1)
                        {
                            foreach (DataRow row in productos.Rows)
                            {
                                var producto = miDaoProducto.ProductoBasico(row["Codigo"].ToString());
                                miProducto = new ProductoFacturaProveedor();
                                miProducto.Id = Convert.ToInt32(row["Id"]);
                                miProducto.IdFactura = Convert.ToInt32(row["Numero"]);
                                miProducto.Producto.CodigoInternoProducto = row["Codigo"].ToString();
                                miProducto.Inventario.IdMedida = Convert.ToInt32(row["IdMedida"]);
                                miProducto.Inventario.IdColor = Convert.ToInt32(row["IdColor"]);
                                miProducto.Lote.Id = Convert.ToInt32(row["IdLote"]);
                                miProducto.Cantidad = Convert.ToInt32(row["Cantidad"]);
                                miProducto.Producto.ValorVentaProducto = Convert.ToInt32(row["Valor"]);
                                miProducto.Producto.ValorIva = ((Producto)producto[0]).ValorIva;
                                miProducto.Producto.Descuento = Convert.ToDouble(row["Descuento"]);
                                miDaoFacturaProducto.EditarProductoFacturaProveedor(miProducto);
                            }
                        }
                        else
                        {
                            foreach (DataRow row in productos.Rows)
                            {
                                miProducto = new ProductoFacturaProveedor();
                                miProducto.Id = Convert.ToInt32(row["Id"]);
                                miProducto.IdFactura = Convert.ToInt32(row["Numero"]);
                                miProducto.Producto.CodigoInternoProducto = row["Codigo"].ToString();
                                miProducto.Inventario.IdMedida = Convert.ToInt32(row["IdMedida"]);
                                miProducto.Inventario.IdColor = Convert.ToInt32(row["IdColor"]);
                                miProducto.Lote.Id = Convert.ToInt32(row["IdLote"]);
                                miProducto.Cantidad = Convert.ToInt32(row["Cantidad"]);
                                miProducto.Producto.ValorVentaProducto = Convert.ToInt32(row["Valor"]);
                                miProducto.Producto.ValorIva = 0;
                                miProducto.Producto.Descuento = Convert.ToDouble(row["Descuento"]);
                                miDaoFacturaProducto.EditarProductoFacturaProveedor(miProducto);
                            }
                        }
                    }
                }
                if (factura.Descuento != tempFactura.Descuento)
                {
                    // var productos = ConsultaProductoFacturaProveedor(factura.Id);
                    foreach (DataRow row in productos.Rows)
                    {
                        var producto = new ProductoFacturaProveedor();
                        producto.Id = Convert.ToInt32(row["Id"]);
                        producto.IdFactura = Convert.ToInt32(row["Numero"]);
                        producto.Producto.CodigoInternoProducto = row["Codigo"].ToString();
                        producto.Inventario.IdMedida = Convert.ToInt32(row["IdMedida"]);
                        producto.Inventario.IdColor = Convert.ToInt32(row["IdColor"]);
                        producto.Lote.Id = Convert.ToInt32(row["IdLote"]);
                        producto.Cantidad = Convert.ToInt32(row["Cantidad"]);
                        producto.Producto.ValorVentaProducto = Convert.ToInt32(row["Valor"]);
                        producto.Producto.ValorIva = Convert.ToDouble(row["Iva"]);
                        producto.Producto.Descuento = factura.Descuento;
                        miDaoFacturaProducto.EditarProductoFacturaProveedor(producto);
                    }
                }
                if (factura.Estado != tempFactura.Estado)
                {
                    foreach (DataRow row in productos.Rows)
                    {
                        var inventario = new Inventario();
                        inventario.CodigoProducto = row["Codigo"].ToString();
                        inventario.IdMedida = Convert.ToInt32(row["IdMedida"]);
                        inventario.IdColor = Convert.ToInt32(row["IdColor"]);
                        inventario.Cantidad = Convert.ToInt32(row["Cantidad"]);
                        if (factura.Estado)
                        {
                            miDaoInventario.ActualizarInventario(inventario, false);
                        }
                        else
                        {
                            miDaoInventario.ActualizarInventario(inventario, true);
                        }
                    }
                }
                CargarComando(sqlEditar);
                miComando.Parameters.AddWithValue("id", factura.Id);
                miComando.Parameters.AddWithValue("producto", factura.Proveedor.CodigoInternoProveedor);
                miComando.Parameters.AddWithValue("formaPago", factura.EstadoFactura.Id);
                miComando.Parameters.AddWithValue("numero", factura.Numero);
                miComando.Parameters.AddWithValue("limite", factura.FechaLimite);
                miComando.Parameters.AddWithValue("ingreso", factura.FechaIngreso);
                miComando.Parameters.AddWithValue("estado", factura.Estado);
                miComando.Parameters.AddWithValue("descuento", factura.Descuento);
                miConexion.MiConexion.Open();
                miComando.ExecuteNonQuery();
                miConexion.MiConexion.Close();
                miComando.Dispose();
            }
            catch (Exception ex)
            {
                throw new Exception(EEditarFactura + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }



        /// <summary>
        /// Inicializa una nueva instancia de NpgsqlCommand de tipo StoredProcedure.
        /// </summary>
        /// <param name="cmd">Comando a ejecutar.</param>
        private void CargarComando(string cmd)
        {
            miComando = new NpgsqlCommand();
            miComando.Connection = miConexion.MiConexion;
            miComando.CommandType = CommandType.StoredProcedure;
            miComando.CommandText = cmd;
        }

        /// <summary>
        /// Inicializa una nueva instancia de NpgsqlDataAdapter de tipo StoredProcedure.
        /// </summary>
        /// <param name="cmd">Comando a ejecutar.</param>
        private void CargarAdapter(string cmd)
        {
            miAdapter = new NpgsqlDataAdapter(cmd, miConexion.MiConexion);
            miAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;
        }
    }
}